package com.nononsenseapps.feeder.worker

import android.annotation.SuppressLint
import android.content.Context
import androidx.work.*
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.engine.ext.PartitionSignature
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.gitee.wsl.io.api.removeGet
import com.gitee.wsl.data.store.StoreServer
import com.gitee.wsl.jvm.store.mmkv.MMKVStoreServer
import com.nononsenseapps.feeder.cache.LocalFileCacheManager
import com.nononsenseapps.feeder.db.entity.PreLoadStateHelper
import com.nononsenseapps.feeder.db.room.*
import com.nononsenseapps.feeder.glide.GlideImageLoader
import timber.log.Timber
import java.io.File

class PreLoader (val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) {

    val downloadRequestOptions=RequestOptions.signatureOf(PartitionSignature.DOWNLOAD_PICTURE)
    private val downloadGlide = GlideImageLoader.glide(context).setDefaultRequestOptions(downloadRequestOptions).downloadOnly()
    val localFileCacheManager = LocalFileCacheManager(context)
    val storeServer: StoreServer = MMKVStoreServer.get()

    override suspend fun doWork(): Result {
        var success = false
        Timber.d("preLoader working....")
        if (isOkToSyncAutomatically(context)) {
            syncFeedItemPreLoader(context)
            success=true
        }
        return when (success) {
            true -> Result.success()
            false -> Result.failure()
        }
    }

    @SuppressLint("CheckResult")
    private suspend fun syncFeedItemPreLoader(context: Context){
        val feedItemPreLoadItemDao=AppDatabase.getInstance(context).feedItemPreLoadItemDao()
        feedItemPreLoadItemDao.loadMustPreLoaderItem().onEach {
            feedItemPreLoadItemDao.get(it)?.let{item->
                if(item.isEnclosure){
                    val state = LocalFileCacheManager.getDownLoadState(context,item.preLoadUrl)
                    if(PreLoadStateHelper.isStartAble(state) || PreLoadStateHelper.isError(state)) {
                       localFileCacheManager.startDownLoadFile(item.preLoadUrl)
                    }else if(PreLoadStateHelper.isCompleted(state))
                        feedItemPreLoadItemDao.delete(item)
                } else {
                        downloadGlide.load(item.preLoadUrl).listener(object : RequestListener<File> {

                            var errorCount=storeServer.getPreferenceOrNull(item.preLoadUrl,0)?:0

                            override fun onLoadFailed(
                                e: GlideException?,
                                model: Any?,
                                target: Target<File>?,
                                isFirstResource: Boolean
                            ): Boolean {
                                Timber.d("download failed item:${item.preLoadUrl},error Count:$errorCount,$e ")
                                if(errorCount > 3){
                                    feedItemPreLoadItemDao.delete(item)
                                    storeServer.removeGet<Int>(item.preLoadUrl)
                                }else{
                                    storeServer.putPreference(item.preLoadUrl,++errorCount)
                                }
                                return true
                            }

                            override fun onResourceReady(
                                resource: File?,
                                model: Any?,
                                target: Target<File>?,
                                dataSource: DataSource?,
                                isFirstResource: Boolean
                            ): Boolean {
                                feedItemPreLoadItemDao.delete(item)
                                Timber.d("download  item:${item.preLoadUrl},error Count:$errorCount ")
                                if(errorCount > 0)
                                    storeServer.removeGet<Int>(item.preLoadUrl)
                                return true
                            }
                        }).submit()
                }
            }
        }
    }
}

fun requestFeedItemPreLoader(context: Context){
    val workRequest = OneTimeWorkRequestBuilder<PreLoader>()

    WorkManager.getInstance(context).enqueueUniqueWork("PreLoader",
        ExistingWorkPolicy.KEEP,workRequest.build())
}